home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / basic / qbfaqr01.zip / MIXLANG.DOC < prev    next >
Internet Message Format  |  1992-08-10  |  13KB

  1. Date: 12-30-91 (19:53)
  2. From: HOWARD MENCHER
  3. Subj: MIXED LANGUAGE PROG -1-
  4. ---------------------------------------------------------------------------
  5. Subj: MIXED LANG PROG PART 1
  6. ---------------------------------------------------------------------------
  7. --The following is a list of the versions needed for these routines:
  8.  
  9. BASIC          BASCOM 6.00+          QB 4.00+
  10. QUICK C 1.0 OR C 5.0
  11.  
  12. --Some rules to follow:
  13.  
  14. 1. Use the same math package for both languages (for example using the alt-
  15.    ernate math package in BASCOM 6.00 requires the use of the alternate math
  16.    package in C5.1).
  17. 2. Compile the C, FORTRAN, PASCAL, or MASM routine in the medium or large
  18.    memory model.
  19. 3. The BASIC .OBJ file must be the first .OBJ in the LINK command.
  20. 4. LINK with the /NOE option.
  21. 5. Use the /NOD LINK option when using specific component libraries; these
  22.    libraries must be specified on the library LINK line.
  23. 6. Use the /NOI LINK option when using routines of the same name, but in
  24.    different cases (e.g. upper case vs. lower case- ASUB vs. aSub).
  25. 7. When passing a BASIC string descriptor to a routine DON'T try extending
  26.    its length - a "String Space Corrupt" error will be received.
  27. 8. Both C and BASIC graphics can't be used at the same time; if your C
  28.    libraries were built with graphics included, you will need to rebuild
  29.    them or else multiple definition errors will occur.
  30. 9. Simplified segment directives are used in MASM, this is why MASM 5.00 is
  31.    needed.
  32.  
  33. --To use the executable (.EXE) program in CodeView:
  34.   1. Compile both BASIC and C, FORTRAN, MASM or PASCAL programs with the /ZI
  35.      option.
  36.   2. LINK with the /CO option.
  37.  
  38.  
  39.  
  40. Passing a FIXED LENGTH string to C by NEAR REFERENCE: BAS7.BAS/ C7.C
  41.  
  42.  
  43. DECLARE SUB StringNear CDECL (_
  44.             BYVAL p1o AS INTEGER,_
  45.             SEG p3 AS INTEGER)
  46.  
  47. CLS
  48. DIM a AS STRING * 15
  49.  
  50. a = "This is a test" + CHR$(0)
  51. CALL StringNear(VARPTR(a), LEN(a))
  52.  
  53. END
  54.  
  55.  
  56.  
  57. #include <stdio.h>
  58.  
  59. void StringNear(a,len)
  60.    char near *a;
  61.     int *len;
  62.  
  63.  {
  64.     int i;
  65.     printf("The string is : %s \n\n",a);
  66.     printf(" Index       Value       Character\n");
  67.     for (i=0;i < *len; i++)
  68.        {
  69.          printf("  %2d          %3d            %c\n",i,a[i],a[i]);
  70.        };
  71.  }
  72.  
  73.         <<<<< END PART 1 >>>>>
  74.  
  75. ---------------------------------------------------------------------------
  76. Subj: MIXED LANG PROG PART 2         Conf: (11) QBASIC
  77. ---------------------------------------------------------------------------
  78. Passing FIXED LENGTH String to C by FAR REFERENCE
  79.  
  80.  
  81. DECLARE SUB StringFar CDECL (_
  82.             BYVAL p1o AS INTEGER,_
  83.             BYVAL p1s AS INTEGER,_
  84.             SEG p3 AS INTEGER)
  85.  
  86. CLS
  87. DIM array AS STRING * 15
  88.  
  89. a = "This is a test" + CHR$(0)
  90. CALL StringFar(VARPTR(a), VARSEG(a), LEN(a))
  91.  
  92. END
  93.  
  94.  
  95.  
  96. #include <stdio.h>
  97.  
  98. void StringFar(a,len)
  99.    char far *a;
  100.     int *len;
  101.  
  102.  {
  103.     int i;
  104.     printf("The string is : %s \n\n",array);
  105.     printf(" Index       Value       Character\n");
  106.     for (i=0;i < *len; i++)
  107.        {
  108.          printf("  %2d          %3d            %c\n",i,a[i],a[i]);
  109.        };
  110.  }
  111.  
  112.  
  113.  
  114.  Passing an arrray of VARIABLE LENGTH STRINGS: BAS15.BAS/ C15.C
  115.  
  116.  
  117. DECLARE SUB StringArray CDECL (_
  118.             BYVAL p1o AS INTEGER,_
  119.             BYVAL p2s AS INTEGER)
  120.  
  121. CLS
  122. DIM array$(10)
  123. FOR i = 0 TO 10
  124.   array$(i) = STRING$(9, 65 + i) + CHR$(0)
  125. NEXT i
  126.  
  127. CALL StringArray(VARPTR(array$(0)), VARSEG(array$(0)))
  128.  
  129. END
  130.  
  131.  
  132.  
  133. #include <stdio.h>
  134.  
  135. struct struct_string{   /* structure that looks like a */
  136.      int length;        /* string descriptor      */
  137.      char *address;
  138. };
  139.  
  140. void StringArray(string)
  141.    struct struct_string far *string;
  142.  
  143.  {
  144.     int i;
  145.     printf(" Index  Length    String\n");
  146.     for (i=0;i < 10; i++)
  147.        {
  148.          printf("  %2d     %3d     %s\n",i,string->length,
  149.                 string->address);
  150.          string++;
  151.        };
  152.  }
  153.  
  154. ---------------------------------------------------------------------------
  155. Subj: MIXED LANG PROG PART 3         Conf: (11) QBASIC
  156. ---------------------------------------------------------------------------
  157. Passing an array of FIXED LENGTH STRINGS to C
  158.  
  159.  
  160. DECLARE SUB StringFar CDECL (_
  161.         length%,_
  162.         num%,_
  163.         BYVAL p3o AS INTEGER,_
  164.         BYVAL p3s AS INTEGER)
  165.  
  166. CLS
  167. DIM array(10) AS STRING * 10
  168.  
  169. length% = 10
  170. num% = 3
  171.  
  172. FOR i = 0 TO 10
  173.    array(i) = STRING$(9, 65 + i) + CHR$(0)
  174. NEXT i
  175.  
  176. CALL StringFar(length%, num%, VARPTR(array(0)),_
  177.                 VARSEG(array(0)))
  178.  
  179. END
  180.  
  181.  
  182.  
  183. #include <stdio.h>
  184.  
  185. void StringFar(len,num,array)
  186.    int  *len;
  187.    int  *num;
  188.    char far *array;
  189.  
  190.  {
  191.     int i;
  192.     printf("The string length is : %d \n\n",*len);
  193.     printf("The number of elements is : %d \n\n",*num);
  194.     printf(" Index        String\n");
  195.     for (i=0;i < *num; i++)
  196.        {
  197.          printf("  %2d         %s\n",i,array);
  198.          array=array+*len;
  199.        };
  200.  }
  201.  
  202. ---------------------------------------------------------------------------
  203. Subj: MIXED LANG PROG PART 4         Conf: (11) QBASIC
  204. ---------------------------------------------------------------------------
  205. Passing an array of USER DEFINED TYPES to C
  206.  
  207.  
  208. TYPE record
  209.    a AS INTEGER
  210.    b AS STRING * 20
  211.    c AS SINGLE
  212. END TYPE
  213.  
  214. DECLARE SUB TypeArray CDECL (_
  215.             BYVAL p1o AS INTEGER,_
  216.             BYVAL p1s AS INTEGER)
  217.  
  218. CLS
  219. DIM element(10) AS record
  220.  
  221. FOR I = 0 TO 10
  222.     element(I).a = 128 + I
  223.     element(I).b = STR$(I) + ". " + DATE$ + CHR$(0)
  224.     element(I).c = 39.6 * I
  225. NEXT I
  226.  
  227. CALL TypeArray(VARPTR(element(0)), VARSEG(element(0)))
  228.  
  229. END
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236. #include <stdio.h>
  237.  
  238. struct record{
  239.        int a;
  240.        char b[20];
  241.        float c;
  242. };
  243.  
  244. void TypeArray(element)
  245.      struct record far *element;
  246.  {
  247.     int i;
  248.     for (i=0;i<3;i++)
  249.       {
  250.         printf("Record[%d].A = %d\n",i,element->a);
  251.         printf("Record[%d].B = %s\n",i,element->b);
  252.         printf("Record[%d].C = %f\n",i,element->c);
  253.         printf("\n");
  254.         element++;
  255.       };
  256.  }
  257.  
  258. ---------------------------------------------------------------------------
  259. Subj: MIXED LANG PROG PART 5         Conf: (11) QBASIC
  260. ---------------------------------------------------------------------------
  261. Passing BASIC 2-D array of VARIABLE LENGTH STRINGS
  262.  
  263.  
  264. DECLARE SUB TwoStringArray CDECL (_
  265.             BYVAL p1o AS INTEGER,_
  266.             BYVAL p1s AS INTEGER)
  267.  
  268. CLS
  269.  
  270. DIM array$(4, 4)
  271.  
  272.  
  273. FOR i = 0 TO 4
  274.  FOR j = 0 TO 4
  275.    array$(i, j) = STRING$(5, 65 + (i + j)) + CHR$(0)
  276.  NEXT j
  277. NEXT i
  278.  
  279. CALL TwoStringArray(VARPTR(array$(0, 0)),_
  280.                     VARSEG(array$(0, 0)))
  281.  
  282. END
  283.  
  284.  
  285.  
  286. #include <stdio.h>
  287.  
  288. struct struct_string{
  289.      int length;
  290.      char *address;
  291. };
  292.  
  293. struct string_array{
  294.      struct struct_string x[5][5];
  295. };
  296.  
  297.  
  298. void TwoStringArray(array)
  299.    struct string_array far *array;
  300.  
  301.  {
  302.     int i,j;
  303.     for (i=0;i < 5; i++)
  304.        {
  305.          for(j=0;j<5;j++)
  306.          {
  307.              printf("  %s  ",array->x[i][j].address);
  308.          };
  309.        printf("\n");
  310.        };
  311.  }
  312.  
  313. <<<< CONTINUED >>>>
  314.  
  315. ---------------------------------------------------------------------------
  316. Subj: MIXED LANG PROG 8              Conf: (11) QBASIC
  317. ---------------------------------------------------------------------------
  318. /***************************************************************************
  319. * This example program should give you some help if you are trying to call
  320. * routines written for QuickBasic from C.  In the process of converting
  321. * many of our QB stuff to C, we found that we didn't want to "give up" the
  322. * nice QB libraries we had.
  323. *
  324. * The problem is, the QB4 manual has some GROSS errors in it concerning
  325. * calling QB stuff from C.  The example on page 310 (passing strings from
  326. * C to QB) is wrong.  It should read:
  327. *
  328. *  char cstr [] = "ABC";
  329. *  struct dodo {
  330. *                int        sd_len;    /* THESE ARE REVERSED IN MANUAL! */
  331. *                char near *sd_addr;   /* MUST DEFINE AS NEAR! */
  332. *              } near str_des;        /* best to define as near */
  333. *
  334. * (Page 307 clearly shows that the 2 byte length comes FIRST and the 2
  335. *  byte address comes second - ever wonder if MS tests their examples?
  336. *  Obviously they didn't in this case!)
  337. *
  338. *
  339. * Rather than going through all the ins-n-outs of why, (because frankly,
  340. * I'm not sure in some cases) I thought I'd simply provide a copy of a
  341. * program we wrote to call a routine written for QB.  Note that the routine
  342. * is an Assembler routine WRITTEN FOR QB (i.e. it isn't written in QB).
  343. * This really doesn't make any difference, but it just lets you know that
  344. * if you have a bunch of commercial QB libraries, you should be able to use
  345. * them with C.
  346. *
  347. * The routine we are calling is called CRC.  It's purpose is to calculate
  348. * a CRC on a record.  (Thanks to Tom Hanlin and Wayne Hammerly of Hammerly
  349. * computers for providing this great routine for QB programmers!)  In
  350. * QB you would call it as:
  351. *
  352. *  CALL CRC(STRING$,HICRC%,LOCRC%)
  353. *
  354. * The string is what you pass to the subroutine, and the HICRC and LOCRC are
  355. * integers returned to you.  We basically want to do the same thing from C.
  356. * The calling sequence in C is:
  357. *
  358. *  crc(&str_des,&hicrc,&locrc);
  359. *
  360. * Note that you have to set the C program up to handle all this as shown in
  361. * the program.
  362. *
  363. * By the way, this program was compiled under large model and worked fine.
  364. * The only thing we wanted to do later was pass a string which had been
  365. * malloc'ed.  This meant that it was no longer a NEAR string and could not
  366. * possibly be NEAR (i.e. defined within the function itself.)  We had to
  367. * actually modify the assembler source to get this working since near stuff
  368. * passes only a two byte address (which is what QB routines expect.)  So,
  369. * make SURE you define everything you are going to passing to QB routines
  370. * as NEAR or use medium or small model (where everything is near by default.)
  371. *
  372. * I am sorry that I could NOT include the CRC.OBJ module with this file.
  373. * I didn't because I didn't write it and it belongs to Tom Hanlin and Wayne
  374. * Hammerly.  But, chances are, if you're reading this you are aware of the
  375. * ADVBAS series for QB.  You can simply use the CRC module found in that
  376. * library.  If you don't have ADVBAS (library for QB) I suggest you download
  377. * it from CompuServe or any of the thousands of BBS's which have it.  By
  378. * the way, PROBAS (the commercial version of ADVBAS) also has CRC in it.
  379. * (Actually, I used CRC2 from PROBAS which is faster because it does a
  380. * table lookup for CRC.  CRC2 called from my C program is lightning fast!)
  381. *
  382. * By the way, I've only been coding in C for about 8 days now so if you see
  383. * any gross inefficiency or my explanation isn't correct "to the letter"
  384. * please forgive me.  But, I'm sure there are a lot of QB/C programmers out
  385. * there who will find this information useful regardless of any small
  386. * inaccuracies there may be in the explanation.
  387. *
  388. *  Jim Kloss
  389. *  Nochange Software - Home of "XChange" Unattended File Transfer
  390. *  540 Silver Pine Trail
  391. *  Roswell, GA 30076-3323
  392. *  (404)587-3815 voice
  393. *  (404)641-8270 data
  394. ****************************************************************************/
  395.  
  396. ---------------------------------------------------------------------------
  397. Subj: MIXED LANG PROG PART 9         Conf: (11) QBASIC
  398. ---------------------------------------------------------------------------
  399.  
  400. #include <string.h>
  401. #include <stdio.h>
  402.  
  403. /***************************************************************************
  404. * The format for the routine is CRC2(STRING$,HICRC%,LOCRC%) where we pass
  405. * it the STRING$ and it returns the HICRC% and LOCRC%.  Note that we must
  406. * define the routine as 'fortran' (or 'pascal') to tell C that the
  407. * parameters are put onto the stack in the exact opposite order that it
  408. * normally puts them on.  (No, there is not a 'basic' that I know of...)
  409. * The following statement is required to tell C about the QB function.  It
  410. * is a prototype really and defines the kinds of variables you will be
  411. * sending and receiving.
  412. ****************************************************************************/
  413. extern void fortran crc2(struct dodo near *,int near *, int near *);
  414.  
  415. /***************************************************************************
  416. * Everything must be declared NEAR which basic is going to work with since
  417. * it must work in the default data segment.
  418. ****************************************************************************/
  419. struct dodo {
  420.               unsigned int        sd_len;
  421.               unsigned char near *sd_addr;
  422.             }  near str_des;
  423.  
  424. /***************************************************************************
  425. * Main Program.
  426. ****************************************************************************/
  427. void main()
  428. {
  429.  
  430.    char temp[200];
  431.    unsigned hicrc,locrc;
  432.  
  433.    strcpy(temp,"This is a test.");   /* results should be 236 and 29 as hi/lo *
  434.  
  435.    str_des.sd_addr = temp;
  436.    str_des.sd_len  = strlen(temp);
  437.  
  438.    hicrc=locrc=0;
  439.  
  440.    printf("%u is the hicrc and %u is the locrc before call on %s\n",hicrc,locrc
  441.    crc(&str_des,&hicrc,&locrc);
  442.    printf("%u is the hicrc and %u is the locrc after call on %s\n",hicrc,locrc,
  443.    printf("If everything worked right, the results should be 236 and 29!");
  444. }
  445.  
  446.                              HOWIE
  447.